package com.kotlin.demo.net

import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.jsonObject
import org.apache.commons.codec.binary.Base64
import java.net.HttpURLConnection
import java.net.URL
import java.nio.charset.StandardCharsets
import java.security.MessageDigest
import javax.crypto.Cipher
import javax.crypto.spec.SecretKeySpec

class TranslatorError(message: String) : Exception(message)

/**
 * 爱词霸翻译API
 */
class Iciba {
    private val defaultSessionFreq = 1000
    private val defaultSessionSeconds = 1500.0
    private val hostUrl = "https://www.iciba.com/fy"
    private val apiUrl = "https://ifanyi.iciba.com/index.php"
    private val signKey = "6dVjYLFyzfkFkk"
    private val encryptKey = "L4fBtD5fLC9FQw22"
    private val decryptKey = "aahc3TfyfCEmER33"
    private val inputLimit = 3000

    private fun getSign(queryText: String): String {
        val cryText = "6key_web_new_fanyi$signKey$queryText"
        val md = MessageDigest.getInstance("MD5")
        val sign = md.digest(cryText.toByteArray()).joinToString("") { "%02x".format(it) }.substring(0, 16)
        val cipher = Cipher.getInstance("AES/ECB/PKCS5Padding")
        val secretKey = SecretKeySpec(encryptKey.toByteArray(), "AES")
        cipher.init(Cipher.ENCRYPT_MODE, secretKey)
        val encrypted = cipher.doFinal(sign.toByteArray())
//        return Base64.encodeToString(encrypted, Base64.DEFAULT)
//        return String(Base64.getEncoder().encode(encrypted))
        return String(Base64.encodeBase64(encrypted))
    }

    private fun getResult(content: String): JsonObject {
        val cipher = Cipher.getInstance("AES/ECB/PKCS5Padding")
        val secretKey = SecretKeySpec(decryptKey.toByteArray(), "AES")
        cipher.init(Cipher.DECRYPT_MODE, secretKey)
//        val decoded = Base64.decode(content.toByteArray(StandardCharsets.UTF_8))
        val decoded = Base64.decodeBase64(content.toByteArray(StandardCharsets.UTF_8))
        val decrypted = cipher.doFinal(decoded)
        val json = Json.parseToJsonElement(String(decrypted))
//        val json = JSON.parseObject(String(decrypted))
        return json.jsonObject
    }

    // 优化 icibaApi 方法，添加日志输出和错误处理
    suspend fun icibaApi(
        queryText: String,
        fromLanguage: String = "auto",
        toLanguage: String = "en"
    ): String = withContext(Dispatchers.IO) {
        try {
            if (queryText.length > inputLimit) {
                throw TranslatorError("Input text too long")
            }

            val params = mapOf(
                "c" to "trans",
                "m" to "fy",
                "client" to "6",
                "auth_user" to "key_web_new_fanyi",
                "sign" to getSign(queryText)
            )

            val payload = mapOf(
                "from" to fromLanguage,
                "to" to if (fromLanguage == "auto") "auto" else toLanguage,
                "q" to queryText
            )

            val url = URL("$apiUrl?${params.map { "${it.key}=${it.value}" }.joinToString("&")}")
            val connection = url.openConnection() as HttpURLConnection
            connection.requestMethod = "POST"
            connection.doOutput = true
            connection.outputStream.use { it ->
                it.write(
                    payload.map { "${it.key}=${it.value}" }.joinToString("&").toByteArray()
                )
            }

            if (connection.responseCode == HttpURLConnection.HTTP_OK) {
                val response = connection.inputStream.bufferedReader().use { it.readText() }
                val json = Json.parseToJsonElement(response).jsonObject
                val content = json["content"]?.toString() ?:  ""
                val result = getResult(content)
                //移除头尾的引号
                 result["out"]?.toString()?.removeSurrounding("\"") ?: ""
            } else {
                throw TranslatorError("API request failed: ${connection.responseCode}")
            }
        } catch (e: Exception) {
            println("Error in icibaApi: ${e.message}")
            throw e
        }
    }
}

// 使用示例
suspend fun main() {
    val iciba = Iciba()
    try {
        val result = iciba.icibaApi("热水", fromLanguage = "zh", toLanguage = "en")
        println(result.removeSurrounding("\""))
    } catch (e: Exception) {
        println(e.message)
    }
}